#ifndef SIMPLE_SUPPORT_ALGORITHM_REACHES_HPP
#define SIMPLE_SUPPORT_ALGORITHM_REACHES_HPP

#include <iterator> // std::begin std::end

#include "traits.hpp" // iterable equality_comparable
#include "../type_traits/conversions.hpp" // converts_to

namespace simple::support
{

	template <typename It, typename It2>
	[[nodiscard]] constexpr
	auto reaches(const It& one, const It2& other) noexcept(noexcept(one == other))
	requires (iterable<It> || iterable<It2>) && equality_comparable<It, It2>
	{
		return one == other;
	}

	struct unreachable {};
	[[nodiscard]] constexpr
	bool reaches(const iterable auto &, unreachable) noexcept
	{ return false; }

	template<typename R>
	concept sequence = []()
	{
		using std::begin;
		using std::end;
		return requires(R r)
		{
			{begin(r)} -> iterable;
			{reaches(begin(r),end(r))} -> converts_to<bool>;
		};
	}();

} // namespace simple::support

#endif /* end of include guard */
